/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

/**
 * 双向映射表，严格按照一对一映射关系
 */
export class BidirectionalMap<T, U> {
  private readonly forwardMap: Map<T, U>;
  private readonly reverseMap: Map<U, T>;

  constructor() {
    this.forwardMap = new Map<T, U>();
    this.reverseMap = new Map<U, T>();
  }

  /**
   * 用键索引值
   * @param {T} key
   * @returns {U | undefined}
   */
  getByKey(key: T): U | undefined {
    return this.forwardMap.get(key);
  }

  /**
   * 用值索引键
   * @param {U} value
   * @returns {T | undefined}
   */
  getByValue(value: U): T | undefined {
    return this.reverseMap.get(value);
  }

  /**
   * 检查键是否存在
   * @param {T} key
   * @returns {boolean}
   */
  checkByKey(key: T): boolean {
    return key !== undefined && this.forwardMap.has(key);
  }

  /**
   * 检查值是否存在
   * @param {U} value
   * @returns {boolean}
   */
  checkByValue(value: U): boolean {
    return value !== undefined && this.reverseMap.has(value);
  }

  /**
   * 添加键值对
   * @param {[T, U]} pair
   */
  set(pair: [T, U]): void {
    this.forwardMap.set(pair[0], pair[1]);
    this.reverseMap.set(pair[1], pair[0]);
  }

  /**
   * 按键删除键值对
   * @param {T} key
   */
  deleteByKey(key: T) {
    if (this.checkByKey(key)) {
      this.reverseMap.delete(this.getByKey(key)!);
      this.forwardMap.delete(key);
    }
  }

  /**
   * 按值删除键值对
   * @param {U} value
   */
  deleteByValue(value: U) {
    if (this.checkByValue(value)) {
      this.forwardMap.delete(this.getByValue(value)!);
      this.reverseMap.delete(value);
    }
  }
}
